﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace QT.Net
{
    /// <summary>
    /// IP配置信息结构体
    /// </summary>
    public struct NetInfo
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string Name;
        /// <summary>
        /// 描述
        /// </summary>
        public string Description;
        /// <summary>
        /// IP地址
        /// </summary>
        public string IP;
        /// <summary>
        /// 子网掩码
        /// </summary>
        public string Mask;
        /// <summary>
        /// 网关
        /// </summary>
        public string GateWay;
        /// <summary>
        /// DNS
        /// </summary>
        public string Dns;
    }

    /// <summary>
    /// 网络操作方法
    /// </summary>
    public class NetWork
    {
        /// <summary>
        /// 判断给定IP是否能够Ping通
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <returns>bool</returns>
        public static bool ping(string ip)
        {
            if (IsIP(ip))
            {
                Ping p = new Ping();
                PingReply preply;
                try
                {
                    preply = p.Send(ip);
                }
                catch
                {
                    return false;
                }

                if (preply.Status == IPStatus.Success) return true;
                else return false;
            }
            else
            {
                return false;
            }
        }
        
        /// <summary>
        /// 判断给定IP是否能够Ping通
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <param name="time">超时时间</param>
        /// <returns>bool</returns>
        public static bool ping(string ip, int time)
        {
            if (IsIP(ip))
            {
                Ping p = new Ping();
                PingReply preply;
                try
                {
                    preply = p.Send(ip, time);
                }
                catch
                {
                    return false;
                }

                if (preply.Status == IPStatus.Success) return true;
                else return false;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 判断给定IP是否为合法IP
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <returns>bool</returns>
        public static bool IsIP(string ip)
        {
            try
            {
                IPAddress IP;
                bool Bool = IPAddress.TryParse(ip, out IP);
                return Bool;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 使用正则表达式判断IP是否为合法IP
        /// </summary>
        /// <param name="ip">待检查IP</param>
        /// <returns>bool</returns>
        public static bool CheckIP(string ip)
        {
            Regex rgx = new Regex(@"^[0-2]{0,1}[0-9]{1,2}(\.[0-2]{0,1}[0-9]{1,2}){3}$");
            if (!rgx.IsMatch(ip))
            {
                return false; ;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 检查子网掩码是否正确
        /// </summary>
        /// <param name="mask">子网掩码</param>
        /// <returns>bool</returns>
        public static bool CheckMask(string mask)
        {
            long mask_Int = IP.IPToLong(mask);
            string mask_Binary = Convert.ToString(mask_Int, 2);
            Regex rgx = new Regex(@"01");
            if (rgx.IsMatch(mask_Binary)) return false;

            return true;
        }

        /// <summary>
        /// 判断给定IP是否为IPv6
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <returns>bool</returns>
        public static bool IsIPv4(string ip)
        {
            try
            {
                IPAddress IP = IPAddress.Parse(ip);
                if (IP.AddressFamily == AddressFamily.InterNetwork)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 判断给定IP是否为IPv4
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <returns>bool</returns>
        public static bool IsIPv6(string ip)
        {
            try
            {
                IPAddress IP = IPAddress.Parse(ip);
                if (IP.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// IP转换为long数值
        /// </summary>
        /// <param name="ip">待转换IP</param>
        /// <returns>long</returns>
        public static long ToInt(string ip)
        {
            string newIP="";
            string[] ips = ip.Split('.');
            for (int i = 0; i < ips.Length; i++)
            {
                ips[i] = ips[i].PadLeft(3, '0');

                newIP += ips[i];
            }

            return Convert.ToInt64(newIP);
        }

        /// <summary>
        /// 对比两个IP，返回ip1与ip2的差值
        /// </summary>
        /// <param name="ip1">ip1</param>
        /// <param name="ip2">ip2</param>
        /// <returns>long</returns>
        public static long Compare(string ip1, string ip2)
        {
            return ToInt(ip1) - ToInt(ip2);
        }

        /// <summary>
        /// 获取本机IP
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIps()
        {
            StringBuilder sbRetn = new StringBuilder();
            foreach (IPAddress ip in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                sbRetn.AppendFormat("{0},", ip.ToString());
            }
            return sbRetn.ToString().TrimEnd(new char[] { ',' });
        }

        /// <summary>
        /// 获取网络连接
        /// </summary>
        /// <returns>NetInfo</returns>
        public static NetInfo GetNetInfo()
        {
            NetInfo Info = new NetInfo();
            Info.Name = "";
            Info.Description = "";
            Info.IP = "";
            Info.Mask = "";
            Info.GateWay = "";
            Info.Dns = "";

            NetworkInterface[] NetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface NetworkIntf in NetworkInterfaces)
            {
                if (NetworkIntf.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                {
                    Info.Name = NetworkIntf.Name;
                    Info.Description = NetworkIntf.Description;

                    IPInterfaceProperties IPInterfaceProperties = NetworkIntf.GetIPProperties();

                    //获取本机IP地址信息，子网掩码信息
                    UnicastIPAddressInformationCollection UnicastIPAddressInformationCollections = IPInterfaceProperties.UnicastAddresses;
                    if (UnicastIPAddressInformationCollections.Count > 0)
                    {
                        for (int i = 0; i < UnicastIPAddressInformationCollections.Count; i++)
                        {
                            if (UnicastIPAddressInformationCollections[0].SuffixOrigin == SuffixOrigin.Manual)
                            {

                                Info.IP = UnicastIPAddressInformationCollections[0].Address.ToString();
                                Info.Mask = UnicastIPAddressInformationCollections[0].IPv4Mask == null ? "" : UnicastIPAddressInformationCollections[0].IPv4Mask.ToString();
                            }
                        }
                    }

                    //获取本机网关
                    GatewayIPAddressInformationCollection GWAddress = IPInterfaceProperties.GatewayAddresses;
                    if (GWAddress.Count > 0)
                    {
                        Info.GateWay = GWAddress[0].Address.ToString();
                    }

                    //获取本机DNS
                    IPAddressCollection DNSAddress = IPInterfaceProperties.DnsAddresses;
                    foreach (IPAddress dns in DNSAddress)
                    {
                        Info.Dns += "," + dns;
                    }
                    Info.Dns.Remove(0, 1);
                }
            }
            return Info;
        }
    }
}
